package entity;


import org.newdawn.slick.geom.Line;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Shape;
import physics.CollisionClass;

/**
 *
 * @author ant
 * 
 * a concrete object to represent walls stored in the tile map. thus, no
 * need to render.
 */
public class Wall extends GameObject
{
    //rather than dynamically create, just store these.
    private Line leftEdge, rightEdge, topEdge, bottomEdge;
    //amount of to bounce away from wall
    private float wallBounceMargin = 2;
    public Wall(Rectangle collisionShape)
    {
        this.collisionShape = collisionShape;
        collisionClass = CollisionClass.environmetalObj;
        
        leftEdge = new Line(collisionShape.getMinX(), collisionShape.getMinY(),
                            collisionShape.getMinX(), collisionShape.getMaxY());
        rightEdge = new Line(collisionShape.getMaxX(), collisionShape.getMinY(),
                             collisionShape.getMaxX(), collisionShape.getMaxY());
        topEdge = new Line(collisionShape.getMinX(), collisionShape.getMinY(),
            collisionShape.getMaxX(), collisionShape.getMinY());
        bottomEdge = new Line(collisionShape.getMinX(), collisionShape.getMaxY(),
        collisionShape.getMaxX(), collisionShape.getMaxY());
                            
        pos.x = collisionShape.getCenterX();
        pos.y = collisionShape.getCenterY();
    }
    
    /**
     * 
     * @param other 
     * 
     * Push back player/enemy. destroy bullets
     */
    @Override
    public void collide(GameObject other)
    {
        if(other.collisionClass == CollisionClass.enemyProjectile || other.collisionClass == CollisionClass.playerProjectile)
            other.expired = true;
        else if(other.collisionClass == CollisionClass.player || other.collisionClass == CollisionClass.enemy)
        {
            //find out which edge the entity hit and move them away
            
            //corner cases (for circles)
            
            //top-left
            if(topEdge.intersects(other.collisionShape) && leftEdge.intersects(other.collisionShape)){
              double ang = Math.atan2(other.collisionShape.getCenterY()-this.collisionShape.getMinY(),other.collisionShape.getCenterX()-this.collisionShape.getMinX());
              //amount of penetration = radius - distance to corner 
              double dist;
              
              //This amount seems to be to larger than the distance between the block collided with and the player, it launches you off screen radius of other shape also seems to be several times larger than it should be...
              //Math.sqrt((other.collisionShape.getCenterX()+this.collisionShape.getMinX())*(other.collisionShape.getCenterX()+this.collisionShape.getMinX())+(other.collisionShape.getCenterY()+this.collisionShape.getMinY())*(other.collisionShape.getCenterY()+this.collisionShape.getMinY()));
              dist=5.01;//just over the movement vector to be certain to overpower and prevent glitching through wall via floating point error
              other.pos.x += (float)(Math.cos(ang)*dist);
              other.pos.y += (float)(Math.sin(ang)*dist);
            }
            
            //top-right
                else if(topEdge.intersects(other.collisionShape) && rightEdge.intersects(other.collisionShape)){
                double ang = Math.atan2(other.collisionShape.getCenterY()-this.collisionShape.getMinY(),other.collisionShape.getCenterX()-this.collisionShape.getMinX());
                double dist=5.01;
                other.pos.x += (float)(Math.cos(ang)*dist);
                other.pos.y += (float)(Math.sin(ang)*dist);
            }
            
            //bottom left
            else if(bottomEdge.intersects(other.collisionShape) && leftEdge.intersects(other.collisionShape)){
                double ang = Math.atan2(other.collisionShape.getCenterY()-this.collisionShape.getMinY(),other.collisionShape.getCenterX()-this.collisionShape.getMinX());
                double dist=5.01;
                other.pos.x += (float)(Math.cos(ang)*dist);
                other.pos.y += (float)(Math.sin(ang)*dist);  
            }
            
            //bottom right
            else if(bottomEdge.intersects(other.collisionShape) && rightEdge.intersects(other.collisionShape)){
                double ang = Math.atan2(other.collisionShape.getCenterY()-this.collisionShape.getMinY(),other.collisionShape.getCenterX()-this.collisionShape.getMinX());
                double dist=5.01;
                other.pos.x += (float)(Math.cos(ang)*dist);
                other.pos.y += (float)(Math.sin(ang)*dist); 
            } 
            
                
            else if(topEdge.intersects(other.collisionShape)) {
                other.pos.y = topEdge.getMinY() - other.collisionShape.getHeight()/2 - wallBounceMargin;
            }
            else if(bottomEdge.intersects(other.collisionShape)) {
                other.pos.y = bottomEdge.getMaxY() + other.collisionShape.getHeight()/2 + wallBounceMargin;
            }
            
            else if(leftEdge.intersects(other.collisionShape)) {
                other.pos.x = leftEdge.getMinX() - other.collisionShape.getWidth()/2 - wallBounceMargin;
            }
            else if(rightEdge.intersects(other.collisionShape)) {
                other.pos.x = rightEdge.getMaxX() + other.collisionShape.getWidth()/2 + wallBounceMargin;
            }
        }
    }
            
}

